/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#ifndef __VTIMER_H__
#define __VTIMER_H__

#include "../../Utils/vUtils.h"
#include "../../Macros/vMemoryMacros.h"

namespace Vendetta {
	/*!
	 *	Abstract clock class.
	 */
	class vTimer {

	public:
		/*!
		 *	Constructor.
		 */
		vTimer();

		/*!
		 *	Destructor.
		 */
		virtual ~vTimer() = 0;

		/*!
		 *	Update meant to be performed exactly once per frame.
		 */
		virtual vVoid	Update() = 0;

		/*!
		 *	Returns time in miliseconds at frame start.
		 *
		 *	\return time in miliseconds at frame start
		 */
		vInt			Time() const;

		/*!
		 *	Returns frames per second.
		 *
		 *	\return frames per second
		 */
		vReal			FPS() const;

		/*!
		 *	Returns frame time in miliseconds.
		 *
		 *	\return frame time in miliseconds.
		 */
		vReal			FrameTime() const;
		
		/*!
		 *	Returns previous frame time in miliseconds.
		 *
		 *	\return previous frame time in miliseconds.
		 */
		vReal			PrevFrameTime() const;

		/*!
		 *	Returns frame count.
		 *
		 *	\return previous frame time in miliseconds.
		 */
		vInt			FramesCount() const;

		/*!
		 *	Returns average frame time.
		 *
		 *	\return Average frame time.
		 */
		inline vReal	AverageFrameTime() const	{
			return mPerFrameTime / (mFramesCounter > 1 ? (mFramesCounter - 1) : 1) * 0.001f;
		}

		/*!
		 *	Returns very current time in miliseconds.
		 *
		 *	\return current time in miliseconds
		 */
		virtual vInt	CurrentTime() const = 0;

		/*!
		 *	Converts given time in miliseconds to string
		 *
		 *	\param time	Time to convert to vString.
		 *	\return Time in miliseconds converted to string.
		 */
		vString			ToString(vUInt time) const;

	protected:

		vUInt		mStartTime;			//! Clock life start time

		vUInt		mPerFrameTime;		//! Time taken once a frame
		vUInt		mPrevPerFrameTime;	//! Time taken once a frame
		vReal		mFPS;				//! Frames per second
		vReal		mFrameTime;			//! Frame time
		vReal		mPrevFrameTime;		//! Previous frame time
		vUInt		mFramesCounter;		//! Frames counter starting with 0

		vUInt		mLastFPSRefreshTime;	//! Last mFPS refresh time

		#define		NUM_FPS_FRAMES	10	//! Number of previous frames to store info on
		vReal		mPrevFrameTimes[NUM_FPS_FRAMES];	//! Previous frame times to smooth FPS computation
	};
}

#endif //__VTIMER_H__